package com.evil.file.api;

import cn.hutool.core.collection.CollectionUtil;
import com.evil.common.core.constant.ServiceNameConstant;
import com.evil.common.file.dto.FileRespDTO;
import com.evil.common.file.dto.UploadReqDTO;
import com.evil.file.config.FeignErrorDecoder;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * 文件接口
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@FeignClient(name = ServiceNameConstant.FILE_SERVICE, configuration = {FeignErrorDecoder.class})
public interface RemoteFileService {

    /**
     * 新增文件记录 若是头像类型则 修改用户头像信息
     *
     * @param uploadReqDTO 上传信息
     * @return FileRespDTO
     */
    @PostMapping(value = "/upload/file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    FileRespDTO uploadFile(@Validated UploadReqDTO uploadReqDTO);

    /**
     * 获取文件服务Host
     *
     * @return String
     */
    @PostMapping("/remote/file-host")
    String getFileServerHost();

    /**
     * 获取文件URL
     *
     * @param fileId fileId
     * @return Response
     */
    @PostMapping("/remote/file-url/get-by-id")
    String getFileUrlByFileId(@RequestParam("fileId") @NotNull(message = "文件id不能为空") Long fileId);

    /**
     * 获取文件URL
     *
     * @param fileCode fileCode
     * @return Response
     */
    @PostMapping("/remote/file-url/get-by-code")
    String getFileUrlByFileCode(@RequestParam("fileCode") @NotBlank(message = "文件code不能为空") String fileCode);

    /**
     * 获取文件流
     *
     * @param fileId fileId
     * @return Response
     */
    @PostMapping("/remote/file/byte-by-id")
    byte[] getFileByteByFileId(@RequestParam("fileId") @NotNull(message = "文件id不能为空") Long fileId);

    /**
     * 获取文件流
     *
     * @param fileCode fileCode
     * @return Response
     */
    @PostMapping("/remote/file/byte-by-code")
    byte[] getFileByteByFileCode(@RequestParam("fileCode") @NotBlank(message = "文件code不能为空") String fileCode);

    /**
     * 获取文件流
     *
     * @param fileRespDTO fileRespDTO
     * @return Response
     */
    @PostMapping("/remote/file/byte-by-base")
    byte[] getFileByteByFileBase(@Validated @RequestBody FileRespDTO fileRespDTO);

    /**
     * 根据文件id获取文件
     *
     * @param fileId fileId
     * @return FileRespDTO Optional
     */
    @PostMapping("/remote/file/is-exist-by-id")
    Optional<FileRespDTO> isExistBaseByFileId(@RequestParam("fileId") @NotNull(message = "文件id不能为空") Long fileId);

    /**
     * 根据文件id获取文件（不存在抛异常）
     *
     * @param fileId fileId
     * @return FileRespDTO
     */
    @PostMapping("/remote/file/find-by-id")
    FileRespDTO findBaseByFileId(@RequestParam("fileId") @NotNull(message = "文件id不能为空") Long fileId);

    /**
     * 根据文件code获取文件
     *
     * @param fileCode fileCode
     * @return FileRespDTO Optional
     */
    @PostMapping("/remote/file/is-exist-by-code")
    Optional<FileRespDTO> isExistBaseByFileCode(@RequestParam("fileCode") @NotBlank(message = "文件code不能为空") String fileCode);

    /**
     * 根据文件code获取文件（不存在抛异常）
     *
     * @param fileCode fileCode
     * @return FileRespDTO
     */
    @PostMapping("/remote/file/find-by-code")
    FileRespDTO findBaseByFileCode(@RequestParam("fileCode") @NotBlank(message = "文件code不能为空") String fileCode);

    /**
     * 根据文件ids获取文件
     *
     * @param fileIds fileIds
     * @return FileRespDTO 列表
     */
    @PostMapping("/remote/file/for-ids")
    List<FileRespDTO> findBaseByFileIds(@NotEmpty(message = "文件ids不能为空") @RequestBody Collection<Long> fileIds);

    /**
     * 根据文件codes获取文件
     *
     * @param fileCodes fileCodes
     * @return FileRespDTO 列表
     */
    @PostMapping("/remote/file/find-by-codes")
    List<FileRespDTO> findBaseByFileCodes(@NotEmpty(message = "文件codes不能为空") @RequestBody Collection<String> fileCodes);

    /**
     * 根据文件ids获取文件
     *
     * @param fileIds fileIds
     * @return FileRespDTO Map
     */
    default Map<Long, FileRespDTO> findBaseMapByFileIds_Default(Collection<Long> fileIds) {
        if (CollectionUtil.isEmpty(fileIds)) {
            return new HashMap<>();
        }
        return this.findBaseMapByFileIds(fileIds);
    }

    /**
     * 根据文件ids获取文件
     *
     * @param fileIds fileIds
     * @return FileRespDTO Map
     */
    @PostMapping("/remote/file/find-map-by-ids")
    Map<Long, FileRespDTO> findBaseMapByFileIds(@NotEmpty(message = "文件ids不能为空") @RequestBody Collection<Long> fileIds);

    /**
     * 根据文件codes获取文件
     *
     * @param fileCodes fileCodes
     * @return FileRespDTO Map
     */
    @PostMapping("/remote/file/find-map-by-codes")
    Map<String, FileRespDTO> findBaseMapByFileCodes(@NotEmpty(message = "文件codes不能为空") @RequestBody Collection<String> fileCodes);

}
